#pragma once

#include <map>
#include <string>

using namespace std;

#include "pugixml/pugixml.hpp"

namespace topconn
{
    enum class cfgtype_t {
        E_ROOT,
        E_PROTOCAL
    };

    class AttributeableCfg
    {
    protected:
        map<string, string> attributes;
        bool validated;
        string name;
        cfgtype_t cfgtype;
    public:
        AttributeableCfg() : validated(true) {};
        AttributeableCfg(cfgtype_t type) : validated(true), cfgtype(type) {};
        AttributeableCfg(map<string,string>& attr, cfgtype_t type) 
            : validated(true) 
            , attributes(attr)
            , cfgtype(type)
        {};
        virtual ~AttributeableCfg() {};
        virtual inline string& getName() { return name; };

        inline map<string, string>& getAttributes() { return attributes; }
        inline void set(const string& key, const string& value) { attributes[key] = value; }

        inline string get(const string& key)
        {
            string value("");
            auto iter = attributes.find(key);
            if (iter != attributes.end())
                value = iter->second;
            return value;
        }
        inline bool isValidated() { return this->validated; }
        inline void setValidated(bool attrValid) { validated = attrValid; }
        inline cfgtype_t getCfgType() { return cfgtype; };
    };

    class RootCfg : public AttributeableCfg
    {
    private:
        string consoleFormat;
        string consoleEncoding;
    public:
        RootCfg() : AttributeableCfg(cfgtype_t::E_ROOT) {};
        inline void setFormat(const string& format) { this->consoleFormat = format; };
        inline void setEncoding(const string& encoding) { this->consoleEncoding = encoding; };
        inline string& getFormat() { return this->consoleFormat; };
        inline string& getEncoding() { return this->consoleEncoding; };
    };

    class ProtocalCfg : public AttributeableCfg
    {
    private:
        string id;
        string type;
        string desc;
    public:
        ProtocalCfg() : AttributeableCfg(cfgtype_t::E_PROTOCAL) {};
        ProtocalCfg(map<string,string>& attrs) 
            : AttributeableCfg(attrs,cfgtype_t::E_PROTOCAL)
        {};
        inline void setId(const string& id) { this->id = id; };
        inline void setType(const string& type) { this->type = type; };
        inline void setDesc(const string& desc) { this->desc = desc; };
        inline string& getType() { return this->type; };
        inline string& getDesc() { return this->desc; };
        inline string& getId() { return this->id; };
    };


	class TopConnResource 
	{
	public:
		TopConnResource()=default;
		~TopConnResource()=default;

        TopConnResource(map<string,string>& attrs) : m_pc(attrs) {};
		RootCfg& getRootCfg() { return m_rc; };
		ProtocalCfg& getProtocalCfg() { return m_pc; };
	private:
		RootCfg m_rc;
		ProtocalCfg m_pc;
	};    
};